package drds.server.route.route_strategy;

import java.sql.SQLNonTransientException;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import drds.server.cache.LayeredCache;
import drds.server.config.model.Schema;
import drds.server.route.Route;
import drds.server.route.RouteNode;
import drds.server.route.parser.core.ParserFactory;
import drds.server.route.parser.core.ParserResult;
import drds.server.route.parser.core.ShardInfoVisitor;
import drds.server.route.parser.core.SqlParser;
import drds.server.route.parser.core.TableColumnValueSetMap;
import drds.server.route.util.RouteUtil;
import drds.server.sqlparser.parser.StatementParser;
import drds.server.sqlparser.sqlobject.statement.Statement;
import drds.server.sqlparser.sqlobject.statement.query.SelectStatement;

public class RouteStrategy extends AbstractRouteStrategy {

	public static final Logger LOGGER = LoggerFactory.getLogger(RouteStrategy.class);

	@Override
	public Route route(//
			Route route,//
			Schema schema,//
			String sql,//
			LayeredCache cache//
	) throws SQLNonTransientException {

		StatementParser statementParser = new StatementParser(sql);

		Statement statement = statementParser.parseStatement();
		ShardInfoVisitor visitor = new ShardInfoVisitor();
		SqlParser sqlParser = ParserFactory.create(statement);
		sqlParser.parseSql(route, sql, schema, statement, visitor, cache);

		/**
		 * Parser 解析过程中已完成了路由的直接返回
		 */
		if (route.isRouteOk()) {
			return route;
		}

		ParserResult parserResult = sqlParser.getParserResult();
		if (parserResult.getTableNameList() == null || parserResult.getTableNameList().size() == 0) {
			throw new IllegalArgumentException("没有表名");
		}

		if (sqlParser.getParserResult().getTableColumnValueSetMapList().size() == 0) {
			TableColumnValueSetMap tableColumnValueSetMap = new TableColumnValueSetMap();
			sqlParser.getParserResult().addTableColumnValueSetMap(tableColumnValueSetMap);
		}

		SortedSet<RouteNode> routeNodeSet = new TreeSet<RouteNode>();
		for (TableColumnValueSetMap tableColumnValueSetMap : sqlParser.getParserResult().getTableColumnValueSetMapList()) {
			// 多个路由节点均要。。。
			Route tempRoute = RouteUtil.multiTableRoute(route, sqlParser.getParserResult(), schema, tableColumnValueSetMap, isSelect(statement), cache);
			if (tempRoute != null) {
				for (RouteNode routeNode : tempRoute.getRouteNodes()) {
					routeNodeSet.add(routeNode);
				}
			}
		}

		RouteNode[] nodes = new RouteNode[routeNodeSet.size()];
		int i = 0;
		for (Iterator<RouteNode> iterator = routeNodeSet.iterator(); iterator.hasNext();) {
			nodes[i] = iterator.next();
			i++;
		}
		route.setRouteNodes(nodes);

		return route;
	}

	/**
	 * SELECT 语句
	 */
	private boolean isSelect(Statement statement) {
		if (statement instanceof SelectStatement) {
			return true;
		} else {
			return false;
		}
	}
}